require "find"
require "fileutils"
require "date_input_parser.rb"
class FileDeleter

  def initialize(dirname,filter=FilterGenerator.new)
    @filter = filter
    @startDir = dirname
    @fileWithModifiedTimeCache = {}
    generateAbsolutePathFilters
  end
  
  def isModifiedBefore?(fileOrDirName, time)
    temp_time_array=time.split("-")
    tk = Time.mktime(temp_time_array[0],temp_time_array[1],temp_time_array[2])
    File.mtime(fileOrDirName) < tk
  end
  
  def deleteFileAndDirModifiedBeforeSpecifiedDate(time)
    if time.include?"-"
      deleteByAbsoluteTime(time)  
    else
      deleteByTimeRange(time)
    end
  end
  
  def generateAbsolutePathFilters()
    relativePathFolders = @filter.foldersToBeKept
    @absolutePathFolder = Array.new
    relativePathFolders.each{|relativePath|
      absolutePath = File.join(@startDir,relativePath)
      @absolutePathFolder << absolutePath
    }
    @absolutePathFolder
  end

  def deleteByTimeRange(time)
    dateInputParser = DateInputParser.new()
    deleteByAbsoluteTime(dateInputParser.getAbsoluteTime(time))
  end
  
  def deleteFileAndDirWithDefaultTimeRange()
    deleteByTimeRange("1"+DateInputParser::MONTH)
  end
  
  def deleteByAbsoluteTime(time)
    Find.find(@startDir){ |f|
      cacheModifiedTime(f)
      if isModifiedBefore?(f,time)
        if !inFilterList?(f)
          puts "deleting "+f.to_s
          doDelete(f)
        end
      end
    }
    recoverModifiedTime
  end
  
  def cacheModifiedTime(filename)
    @fileWithModifiedTimeCache[filename] = File.mtime(filename)
  end
  
  def recoverModifiedTime
    @fileWithModifiedTimeCache.each{|key,value|
      if File.exists?(key)
        File.utime(Time.now,value,key)
      end
    }
  end
  def doDelete(name)
    if File.file?(name)
      File.delete(name)
    elsif File.directory?(name)
      FileUtils.rm_r(name)
    end  
  end
  
  def inFilterList?(name)
    if @absolutePathFolder.find{|foldername| name==foldername || name.include?(foldername+File::SEPARATOR) || foldername.include?(name+File::SEPARATOR)}
      return true
    else return false
    end
  end
  
  private :doDelete, :deleteByAbsoluteTime, :cacheModifiedTime
end
